﻿
package extremefx.i18n {
	import extremefx.DateTime;
	import extremefx.i18n.Calendar;	

	/**
	 * @author Marcelo Volmaro
	 * TODO: Most of the methods here are not implemented....
	 */
	internal class EastAsianLunisolarCalendar extends Calendar {
		protected var _eraHandler:GregorianEraHandler;
		
		public function EastAsianLunisolarCalendar() {
			super();
			_eraHandler = new GregorianEraHandler();
		}
		
		public override function set twoDigitYearMax(pYear:int):void{ 
			_argumentInRange ("value", pYear, 100, _getMaxYear());
			_twoDigitYearMax = pYear;
		}
		
		public override function getYear(pTime:DateTime):int {
			var rd:int = CCFixed._fromDateTime(pTime);
			return _eraHandler.eraYear([], rd);
		}
		
		public override function isLeapDay(pYear:int, pMonth:int, pDay:int, pEra:int = -1):Boolean {
			return CCEastAsianLunisolar._isLeapMonth (_checkYMDEG(pYear, pMonth, pDay, [pEra]), pMonth);
		}
		
		public override function isLeapYear(pYear:int, pEra:int = -1):Boolean {
			return CCEastAsianLunisolar._isLeapYear (_checkYEG(pYear, [pEra]));
		}
		
		public override function get algorithmType():uint{
			return CalendarAlgorithmType.LUNISOLAR;
		}
		
		public function getCelestialStem(pSexagenaryYear:int):int {
			if (pSexagenaryYear < 1 || 60 < pSexagenaryYear) throw new RangeError ("pSexagenaryYear is less than 0 or greater than 60");
			return (pSexagenaryYear - 1) % 10 + 1;
		}
	
		public function getSexagenaryYear(pTime:DateTime):int {
			return (getYear (pTime) - 1900) % 60;
		}
	
		public function getTerrestrialBranch (pSexagenaryYear:int):int {
			if (pSexagenaryYear < 1 || 60 < pSexagenaryYear) throw new RangeError ("pSexagenaryYear is less than 0 or greater than 60");
			return (pSexagenaryYear - 1) % 12 + 1;
		}
		
		protected function _checkDateTime(pTime:DateTime):void {
			_eraHandler.checkDateTime(pTime);
		}
		
		protected function get actualCurrentEra():int {
			return 1;
		}
		
		protected function _checkEra(pEra:Array):void {
			var era:int = pEra[0];
			if (era == -1) era = actualCurrentEra;
			if (!_eraHandler.validEra(era)) throw new ArgumentError("Era value was not valid.");
			pEra[0] = era;
		}
		
		protected function _checkYEG(pYear:int, pEra:Array):int {
			_checkEra(pEra);
			return _eraHandler.gregorianYear(pYear, pEra[0]);
		}
		
		protected override function _checkYE(pYear:int, pEra:Array):void {
			_checkYEG(pYear, pEra);
		}
		
		protected function _checkYMEG(pYear:int, pMonth:int, pEra:Array):int {
			if (pMonth < 1 || pMonth > 12) throw new RangeError("pMonth", "Month must be between one and twelve.");
			return _checkYEG(pYear, pEra);
		}
		
		protected function _checkYMDEG(pYear:int, pMonth:int, pDay:int, pEra:Array):int {
			var a:int = _checkYMEG(pYear, pMonth, pEra);
			_argumentInRange("day", pDay, 1, getDaysInMonth(pYear, pMonth, pEra[0]));
			return a;
		}

	}
}
